之前都是使用RESTful API開發
換工作面試幾輪之後發現有蠻多家公司都在使用gRPC
就多學一個技能,順便做個筆記
希望可以幫助到也是初接觸gRPC的你
每個topic的最後會附上參考資料,建議要進去看過一遍
全名:gRPC (gRPC Remote Procedure Calls)
是Google發起的一個開源遠端程序呼叫 (Remote procedure call) 系統。該系統基於 HTTP/2 協定傳輸,使用Protocol Buffers 作為介面描述語言。
講幾個gRPC的優點,其他更加詳細的內容可以參照Microsoft Docs有更詳細的說明
文件即是程式結構,程式內不用另外寫object mapping資料
文件透過binary直接轉譯成程式,支援多種語言
資料會經過protobuf編碼,人類無法直接看懂資料,安全性相較於JSON較高(但同時也是缺點,因為人看不懂)
效能透過protobuf序列化後效能較好
參考資料:https://docs.microsoft.com/zh-tw/aspnet/core/grpc/comparison?view=aspnetcore-5.0
有的人在第一次看到protobuf的時候可能會注意到有proto2 與 proto3
使用上建議proto3
因為支援更多種語言,也有做出許多改進
詳細請見參考資料
到網址找適合的你OS binary
https://github.com/protocolbuffers/protobuf/releases
解壓縮,在bin資料夾底下有個protoc
執行go get下載binary
go get github.com/golang/protobuf/protoc-gen-go
撰寫protocol文件
詳細規格可以看文件,以下是簡單tutorial.proto範例
//使用proto3
syntax = "proto3";
//定義所屬package
package tutorial;
//定義輸出的路徑,沒有寫會出現提示警告訊息,但是目前都是生成在執行的資料夾下
//option go_package = "./tutorial";
//定義API interface
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
//定義資料結構
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
}
轉譯成程式碼
轉化為Go程式的command
protoc --go_out=. *.proto
protoc --go_out=plugins=grpc:. *.proto // 用這個比較好,連grpc的service也會跟著轉譯
Read & Write,proto doc在文末有附上
// ProtoExample ...
func ProtoExample() {
// 你一定很好奇這個struct在哪,在tutorial.pb.go
p := HelloRequest{
Name: "Alice",
}
// Writing a Message
bp, err := proto.Marshal(&p)
if err != nil {
log.Fatal(err)
}
// Reading a Message
var data HelloRequest
if err = proto.Unmarshal(bp, &data); err != nil {
log.Fatal(err)
}
log.Println(&data)
}
下載gRPC package
go get -u google.golang.org/grpc
實作API & Server端
type service struct {
UnimplementedGreeterServer
}
func (s *service) SayHello(ctx context.Context, in *HelloRequest) (*HelloReply, error) {
log.Printf("Received: %v", in.GetName())
return &HelloReply{Message: "Hello, " + in.GetName()}, nil
}
// GRPCServer ...
func GRPCServer() {
addr := "127.0.0.1:8080"
lis, err := net.Listen("tcp", addr)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
log.Println("Server listening on", addr)
gRPCServer := grpc.NewServer()
RegisterGreeterServer(gRPCServer, &service{})
if err := gRPCServer.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
實作Client端
const (
address = "127.0.0.1:8080"
defaultName = "world"
)
// GPRCClient ...
func GPRCClient() {
// Set up a connection to the server.
conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := NewGreeterClient(conn)
// Contact the server and print out its response.
name := defaultName
if len(os.Args) > 1 {
name = os.Args[1]
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := c.SayHello(ctx, &HelloRequest{Name: name})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.GetMessage())
}
參考資料:
這是去google搜尋之後看到鐵人賽的文章使用的GUI測試工具
專門用來對gRPC做使用
使用方法
bloomrpc github:https://github.com/uw-labs/bloomrpc
參考的資料非常多,細節很多
文件要多看,只能盡量把作法跟參考資料給集中
總結步驟的話可以分成